package com.alks.function.service.impl.pcfactoryquery;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.excelUtils.nestExcel.NestExcelUtil;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.finance.costcheck.PcPackDetailsReq;
import com.alks.function.data.dto.pcfactoryquery.PartBfInDto;
import com.alks.function.data.dto.pcfactoryquery.PartBfOutDto;
import com.alks.function.data.dto.pcfactoryquery.PartStockDetailDto;
import com.alks.function.data.dto.pcfactoryquery.PartStockHeadDto;
import com.alks.function.data.request.factoryquery.PartBfInRequest;
import com.alks.function.data.request.factoryquery.PartBfOutRequest;
import com.alks.function.data.request.factoryquery.PartStockRequest;
import com.alks.function.data.vo.stock.PartExportVo;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcSlipDetailPartBfMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcSlipPackReasonMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_SdMtlTypePartMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcMtlCheckMapper;
import com.alks.function.service.pcfactoryquery.IPcSlipDetailPartBfService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.ResultCodeEnum.TIME_IS_ERROR;

/**
 * <p>
 * 耗品出入库明细 服务实现类
 * </p>
 *
 * @author ms
 * @since 2023-08-03
 */
@Service
public class PcSlipDetailPartBfServiceImpl extends ServiceImpl<FT_QR_PcSlipDetailPartBfMapper, PcSlipDetailPartBf> implements IPcSlipDetailPartBfService {
    @Autowired
    FT_QR_PcSlipDetailPartBfMapper partBfMapper;
    @Autowired
    FT_QR_PcSlipPackReasonMapper reasonMapper;
    @Autowired
    FT_QR_SdMtlTypePartMapper typeMapper;




    @Override
    @AutoPageAop
    public Map<String, Object> queryPartBfIn(PartBfInRequest request, int printFlag) {
        String companyId = UserIdThread.get().getCompanyId();
        /*时间判断*/
        if (request.getSlipStartDate()!=null&&request.getSlipStartDate().isAfter(LocalDate.now())
                ||request.getSysStartDate()!=null&&request.getSysStartDate().isAfter(LocalDate.now()))
            throw new ServiceErrorException("时间异常");
        /*查询数据*/
        List<PartBfInDto> inDtos=partBfMapper.queryPartBfIn(request,companyId,printFlag);
        /*封装输出*/
        Map<String,Object> map=new HashMap<>(2);
        if (request.getPageNum()!=-1&&request.getPageSize()!=-1) {
            Page<PartBfInDto> page = (Page<PartBfInDto>) inDtos;
            map.put("total",page.getTotal());
        }
        map.put("inDtos",inDtos);
        return map;
    }

    @Override
    public ResponseInfo queryPartBfInBack() {
        /*查询部门*/
        List<String> dept = lambdaQuery().select(PcSlipDetailPartBf::getDeptName)
                .groupBy(PcSlipDetailPartBf::getDeptName)
                .orderBy(true,true,PcSlipDetailPartBf::getDeptName).list()
                .stream().map(PcSlipDetailPartBf::getDeptName).filter(Objects::nonNull).collect(Collectors.toList());
        /*查询厂商*/
        List<String> vendor = lambdaQuery().groupBy(PcSlipDetailPartBf::getVendorName)
                .orderBy(true,true,PcSlipDetailPartBf::getVendorName).list()
                .stream().map(PcSlipDetailPartBf::getVendorName).collect(Collectors.toList());
        /*查询原因*/
        LambdaQueryWrapper<PcSlipPackReason> reasonQuery=new LambdaQueryWrapper<>();
        reasonQuery.select(PcSlipPackReason::getSlipReason).eq(PcSlipPackReason::getSlipType,'I')
                .orderBy(true,true,PcSlipPackReason::getSlipType);
        List<String> reason = reasonMapper.selectList(reasonQuery)
                .stream().map(PcSlipPackReason::getSlipReason).filter(Objects::nonNull).collect(Collectors.toList());
        /*种类查询*/
        LambdaQueryWrapper<SdMtlTypePart> typeQuery=new LambdaQueryWrapper<>();
        typeQuery.select(SdMtlTypePart::getTypeName,SdMtlTypePart::getTypeNo);
        List<SdMtlTypePart> typeParts = typeMapper.selectList(typeQuery);
        /*封装返回值*/
        Map map=new HashMap();
        map.put("dept",dept);
        map.put("vendor",vendor);
        map.put("reason",reason);
        map.put("type",typeParts);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryPartBfOut(PartBfOutRequest request) {
        /*设置分页参数*/
        if (request.getPageNum() == null || request.getPageSize() == null) {
            request.setPageNum(1);
            request.setPageSize(10);
        }
        /*时间判断*/
        if (request.getSlipStartDate()!=null&&request.getSlipStartDate().isBefore(LocalDate.now())) {
            return ResponseInfo.error(TIME_IS_ERROR.getMessage(), TIME_IS_ERROR.getCode());
        }
        /*查询数据*/
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<PartBfOutDto> outDtos=partBfMapper.queryPartBfOut(request);
        Page<PartBfOutDto> page=(Page<PartBfOutDto>) outDtos;
        /*封装输出*/
        Map map=new HashMap();
        map.put("total",page.getTotal());
        map.put("outDtos",outDtos);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryPartBfOutBack() {
        /*查询部门*/
        List<String> dept = lambdaQuery().select(PcSlipDetailPartBf::getDeptName)
                .groupBy(PcSlipDetailPartBf::getDeptName)
                .orderBy(true,true,PcSlipDetailPartBf::getDeptName).list()
                .stream().map(PcSlipDetailPartBf::getDeptName).filter(Objects::nonNull).collect(Collectors.toList());
        /*查询原因*/
        LambdaQueryWrapper<PcSlipPackReason> reasonQuery=new LambdaQueryWrapper<>();
        reasonQuery.select(PcSlipPackReason::getSlipReason).eq(PcSlipPackReason::getSlipType,'I')
                .groupBy(PcSlipPackReason::getSlipReason)
                .orderBy(true,true,PcSlipPackReason::getSlipType);
        List<String> reason = reasonMapper.selectList(reasonQuery)
                .stream().map(PcSlipPackReason::getSlipReason).filter(Objects::nonNull).collect(Collectors.toList());
        /*种类查询*/
        LambdaQueryWrapper<SdMtlTypePart> typeQuery=new LambdaQueryWrapper<>();
        typeQuery.select(SdMtlTypePart::getTypeName,SdMtlTypePart::getTypeNo);
        List<SdMtlTypePart> typeParts = typeMapper.selectList(typeQuery);
        /*封装返回值*/
        Map<String,Object> map=new HashMap(3);
        map.put("dept",dept);
        map.put("reason",reason);
        map.put("type",typeParts);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryPartBfStockHead(PartStockRequest request) {
        /*设置分页参数*/
        if (request.getPageNum() == null || request.getPageSize() == null) {
            request.setPageNum(1);
            request.setPageSize(10);
        }
        /*时间判断*/
        if (request.getInEndDate()!=null&&request.getInEndDate().isBefore(LocalDate.now())
                ||request.getOutEndDate()!=null&&request.getOutEndDate().isBefore(LocalDate.now()))
            return ResponseInfo.error(TIME_IS_ERROR.getMessage(), TIME_IS_ERROR.getCode());
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<PartStockHeadDto> headDtos=partBfMapper.queryPartBfStockHead(request);
        Page<PartStockHeadDto> page=(Page<PartStockHeadDto>) headDtos;
        /*封装返回*/
        Map map=new HashMap();
        map.put("total",page.getTotal());
        map.put("dtos",headDtos);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryPartBfStockDetail(String mtlNo) {
        /*查询入库明细*/
        List<PcSlipDetailPartBf> inList = lambdaQuery().select(PcSlipDetailPartBf::getSlipDate, PcSlipDetailPartBf::getSlipNo
                        , PcSlipDetailPartBf::getSlipReason, PcSlipDetailPartBf::getVendorName, PcSlipDetailPartBf::getQty)
                .eq(PcSlipDetailPartBf::getMtlNo, mtlNo).eq(PcSlipDetailPartBf::getSlipType,"I")
                .orderByAsc(true, PcSlipDetailPartBf::getSlipDate).list();
        /*查询出库明细*/
        List<PcSlipDetailPartBf> outList = lambdaQuery().select(PcSlipDetailPartBf::getSlipDate, PcSlipDetailPartBf::getSlipNo
                        , PcSlipDetailPartBf::getSlipReason, PcSlipDetailPartBf::getDeptName, PcSlipDetailPartBf::getQty)
                .eq(PcSlipDetailPartBf::getMtlNo, mtlNo).eq(PcSlipDetailPartBf::getSlipType, "O")
                .orderByAsc(true, PcSlipDetailPartBf::getSlipDate).list();
        /*拷贝提取*/
        List<PartStockDetailDto> inDtos = BeanUtil.copyList(inList,PartStockDetailDto.class);
        List<PartStockDetailDto> outDtos = BeanUtil.copyList(outList,PartStockDetailDto.class);
        /*封装返回*/
        Map map=new HashMap();
        map.put("inDetail",inDtos);
        map.put("outDetail",outDtos);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo queryPartBfStockBack() {
        /*物料查询*/
        Map<String, String> mtl = lambdaQuery().select(PcSlipDetailPartBf::getMtlName, PcSlipDetailPartBf::getMtlNo)
                .groupBy(PcSlipDetailPartBf::getMtlNo).orderByAsc(true, PcSlipDetailPartBf::getMtlNo)
                .list().stream().collect(Collectors.toMap(PcSlipDetailPartBf::getMtlNo, PcSlipDetailPartBf::getMtlName));

        /*种类查询*/
        LambdaQueryWrapper<SdMtlTypePart> typeQuery=new LambdaQueryWrapper<>();
        typeQuery.select(SdMtlTypePart::getTypeName,SdMtlTypePart::getTypeNo);
        List<SdMtlTypePart> typeParts = typeMapper.selectList(typeQuery);
        /*封装返回*/
        Map map=new HashMap();
        map.put("mtl",mtl);
        map.put("type",typeParts);
        return ResponseInfo.ok(map);
    }

    @Override
    @AutoPageAop
    public ResponseInfo getConsumableList(PcPackDetailsReq req) {
        req.setCompanyId(UserIdThread.get().getCompanyId());
        Map<String, Object> map = new HashMap<>();
        List<PcSlipDetailPartBf2> list = partBfMapper.getConsumableList(req);
        Page<PcSlipDetailPartBf2> page = (Page<PcSlipDetailPartBf2>) list;
        map.put("list",list);
        map.put("total",page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Autowired
    SD_SQ_PcMtlCheckMapper checkMapper;
    @Override
    public ResponseInfo optionConsumable(List<PcSlipDetailPartBf2> list, String remark, String choose) {
        switch (choose){
            case "1":
                for (PcSlipDetailPartBf2 pcSlipDetailPartBf2 : list) {
                    List<PcSlipDetailPartBf2> lists = partBfMapper.getConsumableDetail(pcSlipDetailPartBf2.getSlipNo(),UserIdThread.get().getCompanyId());
                    for (PcSlipDetailPartBf2 slipDetailPartBf2 : lists) {
                        if (slipDetailPartBf2.getPrice() == null) return ResponseInfo.error("单价不能为空");
                    }
                }
                partBfMapper.optionConsumable(list,choose);
                return ResponseInfo.ok("检核成功");
            case "2":
                partBfMapper.optionConsumable(list,choose);
                return ResponseInfo.ok("取消成功");
            case "3":
                for (PcSlipDetailPartBf2 req : list) {
                    PcMtlCheck2 pcMtlCheck2 = new PcMtlCheck2();
                    pcMtlCheck2.setRecNo(req.getSlipNo());
                    String str = checkMapper.getListByRecNo(pcMtlCheck2);
                    if (str == null || "".equals(str)){
                        checkMapper.insertIntoRemark2(pcMtlCheck2,remark);
                    }else {
                        checkMapper.updateRemark2(pcMtlCheck2,remark);
                    }
                }
                return ResponseInfo.ok("成功");
            default:
                return ResponseInfo.error("检查参数");
        }
    }

    @Override
    public ResponseInfo getConsumableDetail(String slipNo) {
        DecimalFormat d1 = new DecimalFormat("0.00000");
        DecimalFormat d2 = new DecimalFormat("0.00");
        List<PcSlipDetailPartBf2> list = partBfMapper.getConsumableDetail(slipNo,UserIdThread.get().getCompanyId());
        for (PcSlipDetailPartBf2 pcSlipDetailPartBf2 : list) {
            if (pcSlipDetailPartBf2.getPrice()!=null)pcSlipDetailPartBf2.setPrices(d1.format(pcSlipDetailPartBf2.getPrice()));
            if (pcSlipDetailPartBf2.getAmt()!=null)pcSlipDetailPartBf2.setAmts(d2.format(pcSlipDetailPartBf2.getAmt()));
        }
        return ResponseInfo.ok(list);
    }

    @Override
    public ResponseInfo saveConsumableDetail(List<PcSlipDetailPartBf2> list) {
        partBfMapper.saveConsumableDetail(list);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo setUnitPrice(List<PcSlipDetailPartBf2> list) {
        Integer i = 0;
        for (PcSlipDetailPartBf2 detailPartBf2 : list) {
            if (detailPartBf2.getPrice()!=null && detailPartBf2.getPrice().doubleValue() >0) continue;
            BigDecimal unitPrice = partBfMapper.getPcUnitPrice(detailPartBf2);
            if (unitPrice!=null) i++;
            unitPrice = unitPrice == null ? new BigDecimal(0) : unitPrice;
            detailPartBf2.setPrice(unitPrice);
            BigDecimal qty = detailPartBf2.getQty() == null ? new BigDecimal(0) : detailPartBf2.getQty();
            BigDecimal amt = unitPrice.multiply(qty, MathContext.DECIMAL32);
            detailPartBf2.setAmts(String.valueOf(amt));
            detailPartBf2.setPrices(String.valueOf(unitPrice));
        }
        partBfMapper.saveConsumableDetail(list);
        return ResponseInfo.ok(i);
    }

    @Override
    public void partInExport(HttpServletResponse response, List<PartBfInDto> inDtoList) {
        String companyId = UserIdThread.get().getCompanyId();
        String excelName = "耗品入库_"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));
        /*写入表头*/
        List<String> heads = new ArrayList<>();
        heads.add("荣阳五金&消耗品入库明细");
        heads.add("导出日期:"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        /*补充数据*/
        List<PartExportVo> voList = PartExportVo.aggregateParts(inDtoList);
        /*数据排序*/
        new NestExcelUtil<PartExportVo>().exportData(voList, List.of(heads), excelName, response);

    }


}
